package com.key.win.business.chat.session;

import com.key.win.base.auth.AuthenticationUtil;
import com.key.win.base.auth.detail.Authentication;
import com.key.win.base.exception.BizException;
import com.key.win.base.util.RedisUtil;
import com.key.win.base.util.SingleSoldierConstantUtils;
import com.key.win.business.chat.eums.ImMessageTargetEnum;
import com.key.win.business.chat.service.ImGroupService;
import com.key.win.business.chat.service.ImGroupUserService;
import com.key.win.business.chat.vo.ImGroupUserFullVo;
import com.key.win.business.chat.vo.ImMessageChatFriendInVo;
import com.key.win.business.chat.vo.ImMessageChatGroupInVo;
import com.key.win.system.model.SysUser;
import com.key.win.system.service.SysUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Component
public class ChatSessionUtil {
    private final static Logger logger = LoggerFactory.getLogger(ChatSessionUtil.class);
    final static String SESSION_NAME_SUFFIX = ":会话";

    public final static Base64.Decoder decoder = Base64.getDecoder();
    public final static Base64.Encoder encoder = Base64.getEncoder();

    private static RedisTemplate<String, Object> redisTemplate;

    private static ImGroupUserService imGroupUserService;

    private static ImGroupService imGroupService;

    public static SysUserService getSysUserService() {
        return sysUserService;
    }

    @Autowired
    public void setSysUserService(SysUserService sysUserService) {
        ChatSessionUtil.sysUserService = sysUserService;
    }

    private static SysUserService sysUserService;

    private static int chatSessionExpires;

    public static ImGroupUserService getImGroupUserService() {
        return imGroupUserService;
    }

    public static ImGroupService getImGroupService() {
        return imGroupService;
    }

    @Autowired
    public void setImGroupService(ImGroupService imGroupService) {
        ChatSessionUtil.imGroupService = imGroupService;
    }

    @Autowired
    public void setImGroupUserService(ImGroupUserService imGroupUserService) {
        ChatSessionUtil.imGroupUserService = imGroupUserService;
    }

    @Value("${spring.global.chat.expires:300}")
    public void setChatSessionExpires(int expires) {
        ChatSessionUtil.chatSessionExpires = expires;
    }

    public static int getChatSessionExpires() {
        return chatSessionExpires;
    }

    @Autowired
    public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
        ChatSessionUtil.redisTemplate = redisTemplate;
    }

    public static String createSessionId(String str1, String str2) {
        return createSessionId(str1 + ":" + str2);
    }


    public static String createSessionId(String str) {
        return encoder.encodeToString(str.getBytes(StandardCharsets.UTF_8));
    }

    public static ChatSession getChatSession(ImMessageChatFriendInVo imMessageChatFriendInVo) {
        ChatSession chatSession = getFriendChatSession(imMessageChatFriendInVo.getFromUserId(), imMessageChatFriendInVo.getToUserId());
        if (chatSession == null) {
            String sessionId = createSessionId(imMessageChatFriendInVo.getFromUserId(), imMessageChatFriendInVo.getToUserId());
            chatSession = new ChatSession();
            chatSession.setSessionId(sessionId);
            String fromUserId = imMessageChatFriendInVo.getFromUserId();
            String toUserId = imMessageChatFriendInVo.getToUserId();
            Authentication onLineUserByUserId = AuthenticationUtil.getOnLineUserByUserId(toUserId);
            String toUserName = "";
            if (onLineUserByUserId == null) {
                SysUser byId = sysUserService.getById(toUserId);
                if (byId != null) {
                    toUserName = byId.getUserName();
                }
            } else {
                toUserName = onLineUserByUserId.getUserName();
            }
            chatSession.setSessionName(AuthenticationUtil.getOnLineUserByUserId(fromUserId).getUserName() + "-" + toUserName + SESSION_NAME_SUFFIX);
            chatSession.addUserId(imMessageChatFriendInVo.getFromUserId());
            chatSession.addUserId(imMessageChatFriendInVo.getToUserId());
            chatSession.setType(ImMessageTargetEnum.FRIEND);
        }
        redisTemplate.opsForValue().set(SingleSoldierConstantUtils.getRedisFriendSessionKey(chatSession.getSessionId()), chatSession, getChatSessionExpires(), TimeUnit.SECONDS);
        return chatSession;
    }

    private static ChatSession getFriendChatSession(String str1, String str2) {
        ChatSession chatSession = getFriendChatSession(createSessionId(str1, str2));
        if (chatSession == null) {
            chatSession = getFriendChatSession(createSessionId(str2, str1));
        }
        return chatSession;
    }

    private static ChatSession getFriendChatSession(String sessionId) {
        String redisFriendSessionKey = SingleSoldierConstantUtils.getRedisFriendSessionKey(sessionId);
        ChatSession chatSession = (ChatSession) redisTemplate.opsForValue().get(redisFriendSessionKey);
        return chatSession;
    }

    public static ChatSession getChatSession(ImMessageChatGroupInVo imMessageChatGroupInVo) {
        String redisGroupSessionKey = SingleSoldierConstantUtils.getRedisGroupSessionKey(createSessionId(imMessageChatGroupInVo.getGroupId()));
        ChatSession chatSession = (ChatSession) redisTemplate.opsForValue().get(redisGroupSessionKey);
        if (chatSession == null) {
            chatSession = new ChatSession();
            List<ImGroupUserFullVo> groupUserByGroupId = imGroupUserService.findGroupUserByGroupId(imMessageChatGroupInVo.getGroupId());
            if (!CollectionUtils.isEmpty(groupUserByGroupId)) {
                ChatSession finalChatSession = chatSession;
                groupUserByGroupId.forEach(gu -> finalChatSession.addUserId(gu.getUserId()));
            }
            chatSession.setSessionName(imGroupService.getById(imMessageChatGroupInVo.getGroupId()).getName() + SESSION_NAME_SUFFIX);
            chatSession.setSessionId(createSessionId(imMessageChatGroupInVo.getGroupId()));
            chatSession.setType(ImMessageTargetEnum.GROUP);
        }
        redisTemplate.opsForValue().set(redisGroupSessionKey, chatSession, getChatSessionExpires(), TimeUnit.SECONDS);
        return chatSession;
    }

    public static ChatSession getChatSession(String sessionkey) {
        return (ChatSession) redisTemplate.opsForValue().get(sessionkey);
    }

    public static void addUserId(String sessionKey, String userId) {
        ChatSession chatSession = (ChatSession) redisTemplate.opsForValue().get(sessionKey);
        if (chatSession == null) {
            logger.error("chat session is null！");
            throw new BizException("会话不存在！");
        }
        chatSession.addUserId(userId);
        redisTemplate.opsForValue().set(sessionKey, chatSession, getChatSessionExpires(), TimeUnit.SECONDS);
    }

    public static void addUserToFriendChatSession(String key, String userId) {
        String redisFriendSessionKey = SingleSoldierConstantUtils.getRedisFriendSessionKey(key);
        addUserId(redisFriendSessionKey, userId);
    }

    public static void addUserToGroupChatSession(String key, String userId) {
        String redisGroupSessionKey = SingleSoldierConstantUtils.getRedisGroupSessionKey(key);
        addUserId(redisGroupSessionKey, userId);
    }

    public static List<ChatSession> getAllChatSession() throws IOException {
        List<ChatSession> chatSessions = new ArrayList<>();
        Cursor<String> cursor = RedisUtil.scan(redisTemplate, SingleSoldierConstantUtils.REDIS_IM_ROOT_KEY_PREFIX + "*", 999);
        while (cursor.hasNext()) {
            ChatSession chatSession = (ChatSession) redisTemplate.opsForValue().get(cursor.next());
            chatSessions.add(chatSession);
        }
        cursor.close();
        return chatSessions;
    }

    public static void main(String[] args) {
        ChatSessionUtil.getFriendChatSession("1-@#$@#$23", "4:222#$#@#@@#%$^&*()*(*&%^$%#@!~66");
        System.out.println("12");
    }
}
